package main

import (
	"fmt"
	"math/rand"
	"time"
)

/**
*  User: zhanbei
*  Date: 2025/10/27
*  Description: 小火车动画 - 经典的火车呼啸而过，带烟雾效果
 */

// 火车的ASCII艺术
var trainFrames = []string{
	`
      ====        ________                ___________
  _D _|  |_______/        \__I_I_____===__|_________|
   |(_)---  |   H\________/ |   |        =|___ ___|   _________________
   /     |  |   H  |  |     |   |         ||_| |_||   _|                \_____A
  |      |  |   H  |__--------------------| [___] |   =|                        |
  | ________|___H__/__|_____/[][]~\_______|       |   -|                        |
  |/ |   |-----------I_____I [][] []  D   |=======|____|________________________|_
__/ =| o |=-~~\  /~~\  /~~\  /~~\ ____Y___________|__|__________________________|_
 |/-=|___|=    ||    ||    ||    |_____/~\___/          |_D__D__D_|  |_D__D__D_|
  \_/      \_O=====O=====O=====O/      \_/               \_/   \_/    \_/   \_/
`,
}

// Smoke 表示一个烟雾粒子
type Smoke struct {
	x       int     // 横坐标
	y       float64 // 纵坐标（使用float便于平滑移动）
	char    string  // 烟雾字符
	life    int     // 生命值
	vx      float64 // x方向的漂移速度
	vy      float64 // y方向的上升速度
	maxLife int
}

// 创建新的烟雾粒子
func newSmoke(x, y int) *Smoke {
	smokeChars := []string{"@", "o", "O", "°", ".", "~", "*", "◦"}
	return &Smoke{
		x:       x,
		y:       float64(y),
		char:    smokeChars[rand.Intn(len(smokeChars))],
		life:    15 + rand.Intn(10),        // 生命值15-25
		vx:      rand.Float64()*0.5 - 0.25, // -0.25 到 0.25 的随机漂移
		vy:      -0.3 - rand.Float64()*0.2, // 向上飘，速度-0.3到-0.5
		maxLife: 25,
	}
}

// 更新烟雾位置
func (s *Smoke) update() {
	s.y += s.vy
	s.x += int(s.vx)
	s.life--
	// 烟雾上升时逐渐向外扩散
	s.vx *= 1.05
}

// 绘制烟雾
func (s *Smoke) draw() {
	if s.life > 0 {
		// 根据生命值选择颜色（从深灰到浅灰）
		if s.life > s.maxLife*3/4 {
			setColor(90) // 深灰
		} else if s.life > s.maxLife/2 {
			setColor(37) // 白色
		} else if s.life > s.maxLife/4 {
			setColor(37) // 白色
		} else {
			setColor(90) // 淡灰
		}
		moveCursor(s.x, int(s.y))
		fmt.Print(s.char)
	}
}

// RunTrain 小火车动画
func RunTrain() {
	rand.Seed(time.Now().UnixNano())
	width, height := getTerminalSize()

	// 隐藏光标
	hideCursor()
	defer showCursor()

	// 清屏
	clearScreen()

	train := trainFrames[0]
	trainWidth := 85 // 火车的大致宽度

	// 显示标题
	moveCursor(width/2-15, 1)
	setColor(93) // 亮黄色
	fmt.Print("🚂 小火车来啦 - 请稍候 🚂")
	resetColor()

	// 火车从右向左移动
	startX := width + 10
	endX := -trainWidth

	// 计算火车的起始Y位置（垂直居中）
	trainLines := 11 // 火车的行数
	startY := (height - trainLines) / 2
	if startY < 3 {
		startY = 3
	}

	// 烟雾粒子列表
	smokes := make([]*Smoke, 0)
	frameCount := 0

	// 动画循环
	for x := startX; x > endX; x -= 2 {
		frameCount++

		// 清除整个区域（包括烟雾区域）
		clearStartY := startY - 15 // 向上扩展清除范围以包含烟雾
		if clearStartY < 3 {
			clearStartY = 3
		}
		for i := clearStartY; i < startY+trainLines; i++ {
			moveCursor(1, i)
			for j := 0; j < width; j++ {
				fmt.Print(" ")
			}
		}

		// 每隔几帧产生新的烟雾（从烟囱位置）
		if frameCount%2 == 0 {
			// 烟囱大致位置在火车头前部，第1行
			chimneyX := x + 6 // 调整到烟囱位置
			chimneyY := startY + 1
			if chimneyX > 0 && chimneyX < width {
				smokes = append(smokes, newSmoke(chimneyX, chimneyY))
			}
		}

		// 更新并绘制烟雾
		activeSmokes := make([]*Smoke, 0)
		for _, smoke := range smokes {
			smoke.update()
			// 只保留还活着且在屏幕内的烟雾
			if smoke.life > 0 && int(smoke.y) >= 3 && int(smoke.y) < height && smoke.x > 0 && smoke.x < width {
				smoke.draw()
				activeSmokes = append(activeSmokes, smoke)
			}
		}
		smokes = activeSmokes

		resetColor()

		// 绘制火车
		lines := splitLines(train)
		for i, line := range lines {
			if startY+i < height {
				// 只绘制在屏幕内的部分
				visibleStart := 0
				drawX := x

				if x < 0 {
					visibleStart = -x
					drawX = 1
				}

				if visibleStart < len(line) {
					visibleEnd := len(line)
					if drawX+visibleEnd-visibleStart > width {
						visibleEnd = visibleStart + (width - drawX)
					}

					if visibleEnd > visibleStart && drawX > 0 && drawX <= width {
						moveCursor(drawX, startY+i)
						setColor(33) // 黄色
						fmt.Print(line[visibleStart:visibleEnd])
						resetColor()
					}
				}
			}
		}

		time.Sleep(40 * time.Millisecond)
	}

	// 清屏并显示结束信息
	clearScreen()
	moveCursor(width/2-12, height/2)
	setColor(93)
	fmt.Println("🚂 火车已驶离！🚂")
	resetColor()
	moveCursor(1, height)
	time.Sleep(1 * time.Second)
}

// 分割字符串为行
func splitLines(s string) []string {
	lines := []string{}
	currentLine := ""

	for _, ch := range s {
		if ch == '\n' {
			lines = append(lines, currentLine)
			currentLine = ""
		} else {
			currentLine += string(ch)
		}
	}

	if currentLine != "" {
		lines = append(lines, currentLine)
	}

	return lines
}
